import json
import logging
from typing import Dict, Any, List
from datetime import datetime
from pathlib import Path
from sqlalchemy.orm import Session
from app.models.database import InteractionRecord, TrainingData
from app.core.config import config
from app.database.crud import get_db

class DataCollector:
    """数据收集与服务"""
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.db = next(get_db())
        self.export_path = Path(config.get('DATA_EXPORT_PATH', './data/training_data'))
    
    def record_interaction(self, interaction_data: Dict[str, Any]):
        """记录用户交互"""
        try:
            record = InteractionRecord(
                user_id=interaction_data.get('user_id', 'anonymous'),
                session_id=interaction_data.get('session_id', ''),
                user_input=interaction_data.get('user_input', ''),
                model_used=interaction_data.get('model_used', ''),
                model_response=interaction_data.get('model_response', ''),
                intent_type=interaction_data.get('intent_type', ''),
                processing_time=interaction_data.get('processing_time', 0.0),
                user_feedback=interaction_data.get('user_feedback', 0)
            )
            
            self.db.add(record)
            self.db.commit()
            
            # 同时添加到训练数据候选
            self._add_to_training_candidates(record)
            
            self.logger.info(f"交互记录已保存: {record.id}")
            
        except Exception as e:
            self.db.rollback()
            self.logger.error(f"保存交互记录失败: {str(e)}")
    
    def _add_to_training_candidates(self, record: InteractionRecord):
        """添加到训练数据候选"""
        # 只有正面反馈或高质量交互才考虑加入训练数据
        if record.user_feedback == 1 or len(record.model_response) > 50:
            training_data = TrainingData(
                source_record_id=record.id,
                model_name=record.model_used,
                input_text=record.user_input,
                output_text=record.model_response,
                quality_score=self._calculate_quality_score(record)
            )
            
            self.db.add(training_data)
            self.db.commit()
    
    def _calculate_quality_score(self, record: InteractionRecord) -> float:
        """计算数据质量评分"""
        score = 0.5  # 基础分
        
        # 正面反馈加分
        if record.user_feedback == 1:
            score += 0.3
        
        # 响应长度适中加分
        response_len = len(record.model_response)
        if 100 <= response_len <= 1000:
            score += 0.1
        
        # 处理时间合理加分
        if record.processing_time < 10.0:  # 10秒内
            score += 0.1
        
        return min(score, 1.0)
    
    def export_training_data(self, model_name: str = None, min_quality: float = 0.7) -> str:
        """导出训练数据"""
        try:
            query = self.db.query(TrainingData).filter(
                TrainingData.selected_for_training == True,
                TrainingData.quality_score >= min_quality
            )
            
            if model_name:
                query = query.filter(TrainingData.model_name == model_name)
            
            training_data = query.all()
            
            # 按模型分组
            data_by_model = {}
            for data in training_data:
                if data.model_name not in data_by_model:
                    data_by_model[data.model_name] = []
                
                data_by_model[data.model_name].append({
                    "instruction": data.input_text,
                    "input": "",
                    "output": data.output_text
                })
            
            # 导出为JSONL文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            
            for model_name, data_list in data_by_model.items():
                filename = f"{model_name}_training_{timestamp}.jsonl"
                filepath = self.export_path / filename
                
                with open(filepath, 'w', encoding='utf-8') as f:
                    for item in data_list:
                        f.write(json.dumps(item, ensure_ascii=False) + '\n')
                
                self.logger.info(f"训练数据已导出: {filepath}, 数量: {len(data_list)}")
            
            return f"成功导出 {len(training_data)} 条训练数据"
            
        except Exception as e:
            self.logger.error(f"导出训练数据失败: {str(e)}")
            return f"导出失败: {str(e)}"
    
    def get_data_stats(self) -> Dict[str, Any]:
        """获取数据统计"""
        total_interactions = self.db.query(InteractionRecord).count()
        total_training_candidates = self.db.query(TrainingData).count()
        selected_training_data = self.db.query(TrainingData).filter(
            TrainingData.selected_for_training == True
        ).count()
        
        # 模型使用统计
        model_stats = {}
        interactions = self.db.query(InteractionRecord.model_used).all()
        for model, in interactions:
            model_stats[model] = model_stats.get(model, 0) + 1
        
        return {
            "total_interactions": total_interactions,
            "training_candidates": total_training_candidates,
            "selected_training_data": selected_training_data,
            "model_usage": model_stats
        }